﻿using AdminModels;
using CoinModels;
using CoinModels.BTCe;
using Entities;
using Entities.CoinEntities.BTCe;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataPool.Tickers
{
    public static class BTCeDataCollector
    {
        private static int maxAttempts = Settings.GetSetting("MaxTickerCollectAttempts", 5);
        public static List<BTCeCoinBase> FailedCoins = new List<BTCeCoinBase>();

        /// <summary>
        /// Pools the data and creates a FailedCoinsList if it is unable to
        /// persist every coin
        /// </summary>
        /// <param name="attempt">Number of Times Attempted, default = 0</param>
        /// <returns>If All Coins Were Persisted</returns>
        public static List<BTCeCoinBase> CollectData(int attempt = 0)
        {
            List<BTCeCoinBase> coinsToAdd = new List<BTCeCoinBase>();
            DateTime addTime = DateTime.Now;
            
            if (attempt < maxAttempts && (FailedCoins.Count > 0 || attempt == 0))
            {
                try
                {
                    List<BTCeCoinBase> coins = new List<BTCeCoinBase>();
                    // If this is the first run through look for all of the coins, otherwise, just the ones that failed
                    if (attempt == 0)
                    {
                        FailedCoins = new List<BTCeCoinBase>();

                        // Grab the list of coins as objects
                        foreach (Type coinType in BTCeCoinBase.TypeOfBTCeCoins)
                        {
                            var coin = coinType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]);
                            coins.Add(coin as BTCeCoinBase);
                        }
                    }
                    else
                    {
                        coins.AddRange(FailedCoins);
                        FailedCoins = new List<BTCeCoinBase>();
                    }

                    foreach (BTCeCoinBase coin in coins)
                    {
                        BTCeCoinBase coinData = null;
                        bool grabbed = false;

                        // Grab each coin, log failures
                        try
                        {
                            coinData = coin.GetCoin();
                            coinData.updatedat = addTime;
                            grabbed = true;
                        }
                        catch (Exception ex)
                        {
                            ErrorLog.SaveLog(ex, "BTCeTickerDataPooler", ErrorType.MarketGrab);
                            FailedCoins.Add(coin);
                        }

                        // Persist the coin
                        if (grabbed)
                        {
                            coinsToAdd.Add(coinData);
                        }
                    }

                    BTCeCoinBase.PersistCoinCollection(coinsToAdd);
                }
                catch (Exception ex)
                {
                    ErrorLog.SaveLog(ex, "BTCeTickerDataPooler", ErrorType.MarketGrab);
                    coinsToAdd = CollectData(++attempt);
                }
            }
            else
            {
                ErrorLog.SaveLog(new Exception("BTCe Data Grab Fail: " + attempt + " failed attempts.")
                    , "BTCeTickerDataPooler", ErrorType.Summary);
            }

            return coinsToAdd;
        }

        /// <summary>
        /// Gets list of most recently collected Coins
        /// </summary>
        /// <returns>List of most recently collected coins</returns>
        public static List<BTCeCoinBase> GetMostRecentBTCeCoins()
        {
            List<BTCeCoinBase> coins = new List<BTCeCoinBase>();
            BTCeEntity[] tempList;

            using (AegirContext db = new AegirContext())
            {
                DateTime mostRecentDate = db.BTCe_Coin.Max(x => x.updatedat) ?? DateTime.MinValue;
                tempList = db.BTCe_Coin.Where(x => x.updatedat == mostRecentDate).ToArray();
            }

            foreach (var entity in tempList)
            {
                coins.Add(BTCeCoinBase.ConvertToModel(entity));
            }

            return coins;
        }
    }
}
